package com.okbihuo.perm.core.boot.config;

import com.okbihuo.perm.core.logger.publisher.LogPublisher;
import com.okbihuo.perm.core.tool.api.BaseException;
import com.okbihuo.perm.core.tool.api.R;
import com.okbihuo.perm.core.tool.api.ResultCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Xyang
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionConfig {

    /**
     * @param request
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R<Object> MethodArgumentNotValidHandler(HttpServletRequest request, MethodArgumentNotValidException e) throws Exception {
        //按需重新封装需要返回的错误信息
        //List<StatusCode> invalidArguments = new ArrayList<>();
        //解析原错误信息，封装后返回，此处返回非法的字段名称，原始值，错误信息\
        log.error(e.getMessage(), e);
        LogPublisher.error("参数校验失败", e.getMessage());
        return R.fail(ResultCode.PARAM_VALID_ERROR);
    }

    /**
     * @param request
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public Object HttpMessageNotReadableHandler(HttpServletRequest request, HttpMessageNotReadableException e) throws Exception {
        log.error(e.getMessage(), e);
        LogPublisher.error("参数无法正常解析", e.getMessage());
        return R.fail(ResultCode.MSG_NOT_READABLE, "参数无法正常解析");
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Object NoHandlerFoundExceptionHandler(NoHandlerFoundException e) throws Exception {
        log.error(e.getMessage(), e);
        LogPublisher.error("链接不存在", e.getMessage());
        return R.fail(ResultCode.NOT_FOUND, "链接不存在");
    }

    @ExceptionHandler(value = DuplicateKeyException.class)
    public Object DuplicateKeyExceptionHandler(DuplicateKeyException e) throws Exception {
        log.error(e.getMessage(), e);
        LogPublisher.error("关键字重复错误", e.getMessage());
        return R.fail(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
    }
    @ExceptionHandler(value = BaseException.class)
    public Object BaseExceptionHandler(BaseException e) {
        log.error(e.getMessage(), e);
        LogPublisher.error(e.getCode().getCode()+"", e.getMessage());
        return R.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    public Object ExceptionHandler(Exception e) {
        log.error(e.getMessage(), e);
        LogPublisher.error(ResultCode.INTERNAL_SERVER_ERROR.getMessage(), e.getMessage());
        return R.fail(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
    }


}